package cn.yuanqiao.archive.liyong.service.impl;

import cn.yuanqiao.archive.appManager.domain.TenantApply;
import cn.yuanqiao.archive.appManager.domain.TenantSysDictData;
import cn.yuanqiao.archive.appManager.mapper.TenantApplyMapper;
import cn.yuanqiao.archive.appManager.service.ITenantSysConfigService;
import cn.yuanqiao.archive.appManager.service.ITenantSysDictTypeService;
import cn.yuanqiao.archive.liyong.domain.ListQuery;
import cn.yuanqiao.archive.liyong.domain.YqVisitkeywords;
import cn.yuanqiao.archive.liyong.mapper.ListQueryMapper;
import cn.yuanqiao.archive.liyong.mapper.YqVisitkeywordsMapper;
import cn.yuanqiao.archive.liyong.service.ListQueryPageService;
import cn.yuanqiao.archive.liyong.service.ListQueryService;
import cn.yuanqiao.common.annotation.Log;
import cn.yuanqiao.common.constant.Constants;
import cn.yuanqiao.common.constant.HttpStatus;
import cn.yuanqiao.common.core.domain.entity.SysRole;
import cn.yuanqiao.common.enums.DbIdEnum;
import cn.yuanqiao.common.exception.ServiceException;
import cn.yuanqiao.common.utils.SnowflakeIdGenerator;
import cn.yuanqiao.common.utils.ZipUtils;
import cn.yuanqiao.common.utils.ip.IpUtils;
import cn.yuanqiao.common.core.page.TableDataInfo;
import cn.yuanqiao.common.utils.SecurityUtils;
import cn.yuanqiao.common.core.domain.entity.SysUser;
import cn.yuanqiao.system.service.impl.SysConfigServiceImpl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import cn.yuanqiao.common.config.YqDatabaseIdProvider;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 目录检索逻辑实现层
 *
 * @ProjectName: ruoyi-modules-system
 * @Package: cn.yuanqiao.archive.liyong.service.impl
 * @ClassName: ListQueryServiceImpl
 * @Author: lenovo
 * @Description: hbWang
 * @Date: 2023/6/27 11:22
 * @Version: 1.0
 */
@Slf4j
@Service
public class ListQueryServiceImpl implements ListQueryService {
    @Autowired
    ListQueryMapper listQueryMapper;

    @Autowired
    private TenantApplyMapper tenantApplyMapper;

    @Autowired
    private YqVisitkeywordsMapper yqVisitkeywordsMapper;

    @Autowired
    private ITenantSysDictTypeService tenantSysDictTypeService;

    @Autowired
    private ListQueryPageService listQueryPageService;
    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    private static String dataBaseId;

    @PostConstruct
    public void getDatabaseId() {
        dataBaseId = sqlSessionFactory.getConfiguration().getDatabaseId();
    }

    @Autowired
    private SysConfigServiceImpl sysConfigService;

    @Override
    public TableDataInfo query(ListQuery listQuery) {
        String categoryId = listQuery.getCategoryId();
        String type = listQuery.getType();
        if ("-1".equals(categoryId)) {
            categoryId = null;
            listQuery.setCategoryId(null);
        }
        if ("-1".equals(type)) {
            type = null;
            listQuery.setType(null);
        }
        if (StringUtils.isEmpty(categoryId) || StringUtils.isEmpty(type)) {
            if (StringUtils.isEmpty(gethead(listQuery))) throw new ServiceException("请先设置表头展示字段,后再进查询!");
        }
        //判断是否查询档案门类
        if (StringUtils.isNotBlank(categoryId) && StringUtils.isNotBlank(type)) {
            return queryCategoryOrType(categoryId, type, listQuery);
        } else if (StringUtils.isNotBlank(categoryId)) {
            return queryCategory(categoryId, listQuery);
        } else if (StringUtils.isNotBlank(type)) {
            return queryType(type, listQuery);
        } else if (StringUtils.isBlank(categoryId) && StringUtils.isBlank(type)) {
            return queryInitial(listQuery);
        }
        return null;
    }

    @Override
    public Long queryCount(ListQuery listQuery) {
        String categoryId = listQuery.getCategoryId();
        String type = listQuery.getType();
        if ("-1".equals(categoryId)) {
            categoryId = null;
            listQuery.setCategoryId(null);
        }
        if ("-1".equals(type)) {
            type = null;
            listQuery.setType(null);
        }
        listQuery.setCount(true);
        //判断是否查询档案门类
        if (StringUtils.isNotBlank(categoryId) && StringUtils.isNotBlank(type)) {
            return queryCategoryOrType(categoryId, type, listQuery).getTotal();
        } else if (StringUtils.isNotBlank(categoryId)) {
            return queryCategory(categoryId, listQuery).getTotal();
        } else if (StringUtils.isNotBlank(type)) {
            return queryType(type, listQuery).getTotal();
        } else if (StringUtils.isBlank(categoryId) && StringUtils.isBlank(type)) {
            return queryInitial(listQuery).getTotal();
        }
        return 0L;
    }

    /**
     * 查询全宗
     *
     * @param menuId
     * @return
     */
    @Override
    public List<Map<String, Object>> queryFonds(String menuId) {
        List<SysRole> roles = SecurityUtils.getLoginUser().getSysUser().getRoles();
        if (roles == null && roles.size() <= 0) {
            return null;
        }
        String collect = roles.stream().map(m -> String.valueOf(m.getRoleId())).collect(Collectors.joining(","));
        Map<String, Object> map = new HashMap<>();
        String tenantCode = SecurityUtils.getTenantCode();
        StringBuilder sql = new StringBuilder("");
        sql.append(" select DISTINCT c.FONDS_CODE,c.FONDS_NAME from " + tenantCode + Constants.BIG_TABLE_NAME_TREESROLE);
        sql.append(" tr LEFT JOIN " + tenantCode + Constants.BIG_TABLE_NAME_TREES);
        sql.append(" t ON t.ID = tr.TREE_ID ");
        sql.append(" LEFT JOIN  MANAGE_FONDS ");
        sql.append(" c ON t.FONDS_ID = c.ID  where c.STATUS = 1  and t.TYPE='f' and tenantcode= '" + tenantCode + "' ");
        if (!SecurityUtils.isDagly()) {
            sql.append(" and tr.ROLE_ID IN (" + collect + ")");
            sql.append(" and tr.MENU_ID = '" + menuId + "' ");
        }
        sql.append(" ORDER BY FONDS_CODE");
        //查询门类信息
        List<Map<String, Object>> categoryList = new ArrayList<>();
        map.put("FONDS_CODE", "-1");
        map.put("FONDS_NAME", "全部");

        if (dataBaseId.equalsIgnoreCase(DbIdEnum.KINGBASE.getCode())) {
            categoryList = listQueryMapper.selectLeftJoinTableData(" FONDS_CODE,FONDS_NAME ", "", "(" + sql.toString() + ")");

        } else {
            categoryList = listQueryMapper.selectLeftJoinTableData(" FONDS_CODE,FONDS_NAME ", "", DbIdEnum.OSCAR.getCode().equalsIgnoreCase(dataBaseId) ? "(" + sql.toString() + ")" : (DbIdEnum.HIGHGO.getCode().equalsIgnoreCase(dataBaseId) ? "(" + sql.toString() + ")" : sql.toString()));
        }
        if (categoryList.size() > 1) {
            categoryList.add(map);
        }
        List<Map<String, Object>> categoryListd = new ArrayList<>();
        if (categoryList != null) {
            categoryListd = categoryList
                    .stream().collect(
                            Collectors.collectingAndThen(
                                    Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(m -> String.valueOf(m.get("FONDS_CODE"))))), ArrayList::new)
                    );
        }
        return categoryListd;
    }


    /**
     * 查询门类信息
     *
     * @param type
     * @return
     */
    @Override
    public Map<String, Object> queryCategory(String type, String menuId, String qzh) {
        List<SysRole> roles = SecurityUtils.getLoginUser().getSysUser().getRoles();
        if (roles == null && roles.size() <= 0) {
            return null;
        }
        String collect = roles.stream().map(m -> String.valueOf(m.getRoleId())).collect(Collectors.joining(","));
        Map<String, Object> map = new HashMap<>();
        String tenantCode = SecurityUtils.getTenantCode();
        StringBuilder sql = new StringBuilder("");
        sql.append(" select c.GROUP_ID,c.ID,c.NAME,c.TYPE from " + tenantCode + Constants.BIG_TABLE_NAME_TREESROLE);
        sql.append(" tr LEFT JOIN " + tenantCode + Constants.BIG_TABLE_NAME_TREES);
        sql.append(" t ON t.ID = tr.TREE_ID ");
        sql.append(" LEFT JOIN " + tenantCode + Constants.BIG_TABLE_NAME);
        sql.append(" c ON t.CATEGORY_ID = c.ID  where c.IS_DEL = 0 and c.GROUP_ID is not null and t.TYPE='a' ");
        if (!SecurityUtils.isDagly()) {
            sql.append(" and tr.ROLE_ID IN (" + collect + ")");
            sql.append(" and tr.MENU_ID = '" + menuId + "' ");
        }
        if (StringUtils.isNotBlank(qzh)) {
            sql.append(" and c.fonds_code ='" + qzh + "' ");
        }
        if (StringUtils.isNotBlank(type) && !"-1".equals(type)) {
            if (type.equals("1")) {
                sql.append(" and c.TYPE in (1,3) ");
            } else if (type.equals("0")) {
                sql.append(" and c.TYPE in (0,1,3) ");
            } else {
                sql.append(" and c.TYPE = '" + type + "' ");
            }
        }
        //查询门类信息
        List<Map<String, Object>> categoryList = new ArrayList<>();
        if (dataBaseId.equalsIgnoreCase(DbIdEnum.KINGBASE.getCode())) {
            categoryList = listQueryMapper.selectLeftJoinTableData(" GROUP_ID, ID,NAME,TYPE ", "", "(" + sql.toString() + ")");

        } else {
            categoryList = listQueryMapper.selectLeftJoinTableData(" GROUP_ID, ID,NAME,TYPE ", "", DbIdEnum.OSCAR.getCode().equalsIgnoreCase(dataBaseId) ? "(" + sql.toString() + ")" : (DbIdEnum.HIGHGO.getCode().equalsIgnoreCase(dataBaseId) ? "(" + sql.toString() + ")" : sql.toString()));
        }
        List<Map<String, Object>> categoryListd = new ArrayList<>();
        if (categoryList != null) {
            categoryListd = categoryList
                    .stream().collect(
                            Collectors.collectingAndThen(
                                    Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(m -> String.valueOf(m.get("ID"))))), ArrayList::new)
                    );
        }
        map.put("categoryList", categoryListd);

        return map;
    }

    /**
     * 查询展示字段信息
     *
     * @return
     */
    @Override
    public List<Map<String, String>> queryFields(com.alibaba.fastjson.JSONObject json) {
        //获取当前登录用户信息SecurityUtils.getTenantCode()
        String categoryId = json.getString("categoryId"); //门类id
        String menuId = json.getString("menuId"); //菜单id
        String groupId = json.getString("groupId");//门类id
        String type = json.getString("type");//类型
        String qzh = json.getString("qzh");//类型
        String tenantCode = SecurityUtils.getTenantCode();
        StringBuilder sql = new StringBuilder("");
        String appData = "";
        String filde = " t.FIELD_CAPTION,t.FIELD_NAME,t.IS_QUERY,t.SHOWTYPE,t.TYPE ";
        if (StringUtils.isNotBlank(groupId) && StringUtils.isNotBlank(type)) {
            filde += " ,t.TH_WIDTH,t.TH_ALIGN ";
        }
        if (StringUtils.isNotBlank(groupId)) {
            sql.append(" and t.GROUP_ID = '" + groupId + "' ");
            //查询应用定义信息
            TenantApply tenantApplyQuery = tenantApplyMapper.selectYqdaApplyModelById(Long.valueOf(menuId),
                    Long.valueOf(categoryId), tenantCode + Constants.TABLE_YQ_APP);
            if (ObjectUtils.isNotEmpty(tenantApplyQuery)) {
                if ("0".equals(type)) {
                    appData = tenantApplyQuery.getJianlistfield();
                }
                if ("1".equals(type)) {
                    appData = tenantApplyQuery.getJuanlistfield();
                }
                if ("3".equals(type)) {
                    appData = tenantApplyQuery.getXiangmulistfield();
                }
                if (StringUtils.isNotBlank(appData)) {
                    sql.append(" and t.FIELD_NAME in  ('" + appData.replace(",", "','") + "') ");
                } else {
                    sql.append(" and t.IS_HIDDEN = 0 and t.IS_SYSTEM = 1 ");
                }
            }
        } else {
            String roleType = "";
            if ("1".equals(type)) {
                roleType = "1,3";
            } else if ("0".equals(type)) {
                roleType = "0,1,3";
            } else {
                roleType = type;
            }
            List<Map<String, Object>> mapList = queryCategoryIds(roleType, menuId, qzh);
            if (ObjectUtils.isEmpty(mapList)) {
                return null;
            }
            String categoryIds = mapList.stream().map(m -> m.get("GROUP_ID").toString()).collect(Collectors.joining(","));
            sql.append(" and t.GROUP_ID  in ( " + categoryIds + ") ");
            sql.append(" and t.IS_HIDDEN = 0 and t.IS_SYSTEM = 1 ");
        }
        if (StringUtils.isNotBlank(type) && !"-1".equals(type)) {
            sql.append(" and t.TYPE in (" + type + ") ");
        } else {
            sql.append(" and t.TYPE in ( 0,1,3 ) ");
        }
        List<Map<String, String>> tabulationData = MDataList(sql.toString(), appData, filde, categoryId, menuId, type, qzh);
        return tabulationData;
    }

    /**
     * 查询元数据方案信息
     *
     * @param sql
     * @return
     */
    public List<Map<String, String>> MDataList(String sql, String appData, String filde, String categoryId, String menuId, String type, String qzh) {
        String tenantCode = SecurityUtils.getTenantCode();
        //查询元数据方案信息
        List<Map<String, Object>> dataList = listQueryMapper.selectMDataListTableData(tenantCode + Constants.BIG_TABLE_M_DATA_LIST, sql);
        List<Map<String, String>> tabulationData = dataList.stream().collect(Collectors.groupingBy(c -> c.get("FIELD_NAME"))).values().stream().map(a ->
        {
            Map<String, String> mm = new HashMap<>();
            mm.put("FIELD_NAME", String.valueOf(a.get(0).get("FIELD_NAME")));
            mm.put("FIELD_CAPTION", a.stream().map(dd -> String.valueOf(dd.get("FIELD_CAPTION"))).distinct().collect(Collectors.joining("/")));
            mm.put("SHOWTYPE", String.valueOf(a.get(0).get("SHOWTYPE")));
            mm.put("TH_WIDTH", String.valueOf(a.get(0).get("TH_WIDTH")));
            mm.put("TH_ALIGN", String.valueOf(a.get(0).get("TH_ALIGN")));
            return mm;
        }).collect(Collectors.toList());
        if (ObjectUtils.isEmpty(tabulationData)) {
            return null;
        }
        //排序 全不全部  门类和type  == -1
        if (StringUtils.isBlank(appData)) {
            if (StringUtils.isNotBlank(categoryId) && StringUtils.isNotBlank(type)) {
                appData = listQueryMapper.selectAppData(tenantCode + "_TABLEHEAD ", "CONTENT", "  " +
                        "type= '" + type + "' and menu_id= '" + menuId + "' and CATEGORY_ID= '" + categoryId + "' " +
                        " and QZH = '" + qzh + "' ");
            }
            // sysConfigService.selectConfigByKey("YQ_ORDERING_RULE");
        }
        if (StringUtils.isNotBlank(appData)) {
            appData = appData.replaceAll("ASC", "").replaceAll("DESC", "").replaceAll("NONE", "");
            List<Map<String, String>> tabulationDataT = new ArrayList<>();
            String[] split = appData.split(",");
            int k = 0;
            for (String ss : split) {
                tabulationDataT.addAll(tabulationData.stream().filter(f -> f.get("FIELD_NAME").toLowerCase().
                        equals(ss.toLowerCase().trim())).collect(Collectors.toList()));
//                for (int j = 0; j < tabulationData.size(); j++) {
//                    if (tabulationData.get(j).get("FIELD_NAME").toString().toLowerCase().equals(split[i].toLowerCase())) {
//                        tabulationData.add(k, tabulationData.remove(j));
//                        k++;
//                    }
//                }
            }
            return tabulationDataT;
        }
        return tabulationData;
    }


    /**
     * 查询表头设置
     *
     * @param listQuery
     * @return
     */
    public String gethead(ListQuery listQuery) {
        String tenantCode = SecurityUtils.getTenantCode();
        String appData = listQueryMapper.selectAppData(tenantCode + "_TABLEHEAD ", "CONTENT", "  " +
                "type= '" + (StringUtils.isEmpty(listQuery.getType()) ? "-1" : listQuery.getType()) + "' and menu_id= '" + listQuery.getMenuId() + "' and CATEGORY_ID= '" + (StringUtils.isEmpty(listQuery.getCategoryId()) ? "-1" : listQuery.getCategoryId()) + "' " +
                " and QZH = '" + listQuery.getQzh() + "' ");
        return appData;
    }


    /**
     * 查询条件
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> queryApply(JSONObject json) {
        String categoryId = json.getString("categoryId"); //门类id
        String menuId = json.getString("menuId"); //菜单id
        String type = json.getString("type"); //0 件 1 卷  3 项目
        String groupId = json.getString("groupId"); //菜单id
        String tenantCode = SecurityUtils.getTenantCode();
        StringBuilder sql = new StringBuilder(" 1=1 ");
        String appData = "";
        if ("-1".equals(categoryId)) {
            return null;
        }
        if ("-1".equals(type)) {
            return null;
        }
        //应用定义表名处理
        TenantApply tenantApply = new TenantApply();
        //查询应用定义信息
        TenantApply tenantApplyQuery = tenantApplyMapper.selectYqdaApplyModelById(Long.valueOf(menuId), Long.valueOf(categoryId), tenantApply.getTableName());
        if (tenantApplyQuery != null) {
            appData = tenantApplyQuery.getJianquery();
            if ("1".equals(type)) {
                appData = tenantApplyQuery.getJuanquery();
            }
            if ("3".equals(type)) {
                appData = tenantApplyQuery.getXiangmuquery();
            }
        }
        if (StringUtils.isNotBlank(appData)) {
            sql.append(" and FIELD_NAME in  ('" + appData.replace(",", "','") + "') ");
        } else {
            sql.append(" and IS_QUERY != 0 ");
        }
        sql.append(" and GROUP_ID = '" + groupId + "' and  type = '" + type + "' ");
        //查询元数据方案信息
        List<Map<String, Object>> dataList = listQueryMapper.selectTableData(tenantCode +
                Constants.BIG_TABLE_M_DATA_LIST, " FIELDTYPE,FIELD_NAME,FIELD_CAPTION,IS_QUERY,SHOWTYPE ", sql.toString());
        List<Map<String, Object>> tabulationData = dataList.stream().collect(Collectors.groupingBy(c -> c.get("FIELD_NAME"))).values().stream().map(a ->
        {
            Map<String, Object> mm = new HashMap<>();
            mm.put("FIELDTYPE", String.valueOf(a.get(0).get("FIELDTYPE")));
            mm.put("FIELD_NAME", String.valueOf(a.get(0).get("FIELD_NAME")));
            mm.put("FIELD_CAPTION", a.stream().map(dd -> String.valueOf(dd.get("FIELD_CAPTION"))).distinct().collect(Collectors.joining("/")));
            mm.put("IS_QUERY", String.valueOf(a.get(0).get("IS_QUERY")));
            mm.put("SHOWTYPE", Integer.parseInt(a.get(0).get("SHOWTYPE").toString()));
            return mm;
        }).collect(Collectors.toList());
        return tabulationData;
    }


    /**
     * 新增查询历史数据
     *
     * @param keyWords
     * @param menuId
     * @return
     */
    public int insertYqVisitkeywords(String keyWords, String menuId) {

        YqVisitkeywords yqVisitkeywords = new YqVisitkeywords();
        yqVisitkeywords.setMenuId(menuId);
        yqVisitkeywords.setKeywords(keyWords);
        yqVisitkeywords.setUserId(String.valueOf(SecurityUtils.getUserId()));
        List<String> list = yqVisitkeywordsMapper.selectYqVisitkeywordsList(yqVisitkeywords, yqVisitkeywords.getTableName());
        if (list != null && list.size() > 0) {
            return 1;
        }
        // 请求的地址
        yqVisitkeywords.setIp(IpUtils.getIpAddr());
        // 请求主机名
        yqVisitkeywords.setMachineName(IpUtils.getHostName());
        // 检索时间
        yqVisitkeywords.setVisitDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        yqVisitkeywords.setKeywords(keyWords);
        yqVisitkeywords.setUserId(String.valueOf(SecurityUtils.getUserId()));
        yqVisitkeywords.setUserName(SecurityUtils.getUsername());
        yqVisitkeywords.setMenuId(menuId);
        return yqVisitkeywordsMapper.insertYqVisitkeywords(yqVisitkeywords, yqVisitkeywords.getTableName());
    }

    /**
     * 查询检索历史
     *
     * @param yqVisitkeywords
     * @return
     */
    public List<String> selectYqVisitkeywordsList(YqVisitkeywords yqVisitkeywords) {
        yqVisitkeywords.setUserId(String.valueOf(SecurityUtils.getUserId()));
        List<String> keyWordsList = yqVisitkeywordsMapper.selectYqVisitkeywordsList(yqVisitkeywords,
                new YqVisitkeywords().getTableName());

        return keyWordsList;
    }


    /**
     * 查询分类
     *
     * @return
     */
    @Override
    public List<Map<String, String>> queryFication(String menuId) {
        String tenantCode = SecurityUtils.getTenantCode();
        List<Map<String, String>> list = new ArrayList<>();
        List<Map<String, Object>> fileMapList = new ArrayList<>();
        //查询档案门类
        if (StringUtils.isNotBlank(menuId)) {
            fileMapList = queryCategoryIds(null, menuId, null);
        } else {
            fileMapList = listQueryMapper.selectTableData(tenantCode +
                    Constants.BIG_TABLE_NAME, " TYPE ", " 1=1 and IS_DEL = 0 and GROUP_ID is not null order by TYPE desc limit 1 ");
        }
        if (fileMapList != null && fileMapList.size() > 0) {
            //查询字典信息
            List<TenantSysDictData> dictList = tenantSysDictTypeService.selectDictDataByType("TENANT_SYS_CATEGORY_FICATION");
            int type = fileMapList.stream().mapToInt(m -> Integer.parseInt(m.get("TYPE").toString())).max().orElse(0);
            // int type = Integer.parseInt(fileMap.get("TYPE").toString());
            if (type >= 0) {
                String label = dictList.stream().filter(f -> f.getDictValue().equals("0")).map(TenantSysDictData::getDictLabel).collect(Collectors.joining(""));
                Map<String, String> map = new HashMap<>();
                map.put("value", "0");
                map.put("label", label);
                list.add(map);
            }
            if (type >= 1) {
                String label = dictList.stream().filter(f -> f.getDictValue().equals("1")).map(TenantSysDictData::getDictLabel).collect(Collectors.joining(""));
                Map<String, String> map = new HashMap<>();
                map.put("value", "1");
                map.put("label", label);
                list.add(map);
            }
            if (type == 3) {
                String label = dictList.stream().filter(f -> f.getDictValue().equals("3")).map(TenantSysDictData::getDictLabel).collect(Collectors.joining(""));
                Map<String, String> map = new HashMap<>();
                map.put("value", "3");
                map.put("label", label);
                list.add(map);
            }
        }
        return list;
    }


    /**
     * 初始化页面
     *
     * @param
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @author hbWang
     * @date 2023/6/29 16:05
     */
    public TableDataInfo queryInitial(ListQuery listQuery) {
        List<Map<String, Object>> mapList = queryCategoryIds(null, listQuery.getMenuId(), listQuery.getQzh());
        if (ObjectUtils.isEmpty(mapList)) {
            return null;
        }
        String itemTableName = mapList.stream().filter(f -> f.containsKey("ITEM_TABLE_NAME") && f.get("ITEM_TABLE_NAME") != null)
                .map(m -> m.get("ITEM_TABLE_NAME").toString()).collect(Collectors.joining("','"));
        String folderTableName = mapList.stream().filter(f -> f.containsKey("FOLDER_TABLE_NAME") && f.get("FOLDER_TABLE_NAME") != null)
                .map(m -> m.get("FOLDER_TABLE_NAME").toString()).collect(Collectors.joining("','"));
        String fileTableName = mapList.stream().filter(f -> f.containsKey("FILE_TABLE_NAME") && f.get("FILE_TABLE_NAME") != null)
                .map(m -> m.get("FILE_TABLE_NAME").toString()).collect(Collectors.joining("','"));
        //获取当前登录用户信息SecurityUtils.getTenantCode()
        String tenantCode = SecurityUtils.getTenantCode();
        //查询元数据方案信息
        String files = listQuery.getFiles();
        if (StringUtils.isNotBlank(files)) {
            files += ",IS_ENTITY,CREATE_ID,GDCS_ID,EFILE_COUNT,MJ";
        }
        List<Map<String, Object>> dataList = listQueryMapper.selectMDataListTableData(tenantCode +
                Constants.BIG_TABLE_M_DATA_LIST, " and t.TYPE in (0,1,3)  and t.FIELD_NAME in ( '" + files.replace(",", "','") + "' )");
        //处理查询字段
        Map<String, String> map = initializationFiled(dataList);
        String unionSql = " UNION ALL ";
        StringBuilder sql = new StringBuilder("");
        //件
        sql.append("select DA_ID, SUB_TABLE_NAME," + map.get("file") + " from " +
                tenantCode + Constants.BIG_TABLE_YQDA + " where IS_DEL = 0 and STATE = '5' ");
        if (StringUtils.isNotBlank(fileTableName)) {
            sql.append(" and SUB_TABLE_NAME in ('" + fileTableName + "')");
        }
        if (StringUtils.isNotBlank(folderTableName)) {
            sql.append(unionSql);
            //卷
            sql.append("select " + " FOLDER_ID as DA_ID , SUB_TABLE_NAME," + map.get("folder") + " from " +
                    tenantCode + Constants.BIG_TABLE_YQFOLDER + " where IS_DEL = 0 and STATE = '5' ");

            sql.append(" and SUB_TABLE_NAME in ('" + folderTableName + "')");
        }
        if (StringUtils.isNotBlank(itemTableName)) {
            sql.append(unionSql);
            //项目
            sql.append("select " + " ITEM_ID as DA_ID,  SUB_TABLE_NAME , " + map.get("item") + " from " +
                    tenantCode + Constants.BIG_TABLE_YQITEM + " where IS_DEL = 0 and STATE = '5' ");
            sql.append(" and SUB_TABLE_NAME in ('" + itemTableName + "')");
        }
        //拼接查询条件
        String query = concatQueryCondition(listQuery, listQuery.getFiles(), " t.");
        String field = map.get("filde") + " ,t.DA_ID,t.SUB_TABLE_NAME ";
        //异步
        if (StringUtils.isBlank(listQuery.getOrder())) {
            String appData = listQueryMapper.selectAppData(tenantCode + "_TABLEHEAD ", "CONTENT", "  " +
                    "type= '-1' and menu_id= '" + listQuery.getMenuId() + "' and CATEGORY_ID= '-1' and qzh ='" + listQuery.getQzh() + "' ");
            if (StringUtils.isNotBlank(appData)) {
                String[] split = appData.split(",");
                List<String> order = new ArrayList<>();
                for (String s : split) {
                    if (!s.contains(" NONE") && field.contains(s.replace(" ASC", "").replaceAll(" DESC", ""))) {
                        order.add(s);
                    }
                }
                if (order != null && order.size() > 0) {
                    listQuery.setOrder(order.stream().collect(Collectors.joining(" NULLS LAST, ")) + " NULLS LAST ");
                }

            }
        }
        SysUser user = SecurityUtils.getLoginUser().getSysUser();
        TableDataInfo tableDataInfo = new TableDataInfo();
        tableDataInfo.setCode(HttpStatus.SUCCESS);
        tableDataInfo.setMsg("查询成功");
        if (listQuery.getCount()) {
            Integer total = listQueryPageService.queryTotal(sql.toString(), query, field, user);
            tableDataInfo.setTotal(total);
            return tableDataInfo;
        }
        CompletableFuture<List<Map<String, Object>>> list = listQueryPageService.queryList(field, sql.toString(), query, listQuery, user, tenantCode);
        //  CompletableFuture<Integer> total = listQueryPageService.queryTotal(sql.toString(), query, sumTableName.toString(), field, user);
        CompletableFuture<Integer> queryCount = listQueryPageService.queryListCount(field, sql.toString(), query, listQuery, user, tenantCode);
        CompletableFuture.allOf(list, queryCount).join();
        try {
            tableDataInfo.setRows(list.get());
            tableDataInfo.setTotal(queryCount.get());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return tableDataInfo;
    }

    /**
     * 查询传门类id和类型的数据
     *
     * @param categoryId 门类id
     * @param type       类型  0 组件  1组卷  3 项目
     * @param listQuery  查询参数
     * @return java.lang.String
     * @author hbWang
     * @date 2023/6/29 15:29
     */
    public TableDataInfo queryCategoryOrType(String categoryId, String type, ListQuery listQuery) {
        //获取当前登录用户信息
        String tenantCode = SecurityUtils.getTenantCode();
        //查询门类信息
        List<Map<String, Object>> categoryList = listQueryMapper.selectTableData(tenantCode + Constants.BIG_TABLE_NAME, "ITEM_TABLE_NAME," +
                "FOLDER_TABLE_NAME,FILE_TABLE_NAME", " ID= " + categoryId);
        if (categoryList == null || categoryList.size() <= 0) {
            return null;
        }
        Map<String, Object> categoryMap = categoryList.get(0);
        //查询元数据方案信息  type, listQuery.getGroupId(), "1"
        List<Map<String, Object>> dataList = mDataList(categoryId, listQuery.getGroupId(), listQuery.getMenuId(), listQuery.getType());
        //需要查询字段
        String field = dataList.stream().map(m -> m.get("FIELD_NAME").toString()).distinct().collect(Collectors.joining(","));
        StringBuffer sql = new StringBuffer("");
        String tableName = "";
        //组件信息
        if (type.equals("0")) {
            sql.append("select DA_ID,SUB_TABLE_NAME , " + field + " from " + tenantCode + Constants.BIG_TABLE_YQDA + " where IS_DEL = 0");
            tableName = categoryMap.get("FILE_TABLE_NAME").toString();
        }
        //组卷
        if (type.equals("1")) {
            sql.append("select  FOLDER_ID as DA_ID,SUB_TABLE_NAME, " + field + " from " + tenantCode + Constants.BIG_TABLE_YQFOLDER + " where IS_DEL = 0");
            tableName = categoryMap.get("FOLDER_TABLE_NAME").toString();
        }
        //项目
        if (type.equals("3")) {
            sql.append("select ITEM_ID as DA_ID,SUB_TABLE_NAME, " + field + " from " + tenantCode + Constants.BIG_TABLE_YQITEM + " where IS_DEL = 0");
            tableName = categoryMap.get("ITEM_TABLE_NAME").toString();
        }
        sql.append("  and STATE = '5' and SUB_TABLE_NAME = '" + tableName + "'");
        //拼接查询条件
        sql.append(concatQueryCondition(listQuery, listQuery.getFiles(), ""));
        //返回数据
        field = field + " ,DA_ID,SUB_TABLE_NAME ";
        if (StringUtils.isBlank(listQuery.getOrder())) {
            String appData = listQueryMapper.selectAppData(tenantCode + "_TABLEHEAD ", "CONTENT", "  " +
                    "type= '" + listQuery.getType() + "' and menu_id= '" + listQuery.getMenuId() + "' and CATEGORY_ID= '" + listQuery.getCategoryId() + "' and qzh ='" + listQuery.getQzh() + "' ");
            if (StringUtils.isNotBlank(appData)) {
                String[] split = appData.split(",");
                List<String> order = new ArrayList<>();
                for (String s : split) {
                    if (!s.contains(" NONE") && field.contains(s.replace(" ASC", "").replaceAll(" DESC", ""))) {
                        order.add(s);
                    }
                }
                if (order != null && order.size() > 0) {
                    listQuery.setOrder(order.stream().collect(Collectors.joining(" NULLS LAST, ")) + " NULLS LAST ");
                }

            }
        }
        //异步
        SysUser user = SecurityUtils.getLoginUser().getSysUser();
        TableDataInfo tableDataInfo = new TableDataInfo();
        tableDataInfo.setCode(HttpStatus.SUCCESS);
        tableDataInfo.setMsg("查询成功");
        if (listQuery.getCount()) {
            Integer total = listQueryPageService.queryTotal(sql.toString(), null, field, user);
            tableDataInfo.setTotal(total);
            return tableDataInfo;
        }
        CompletableFuture<List<Map<String, Object>>> list = listQueryPageService.queryList(field, sql.toString(), null, listQuery, user, tenantCode);
        // CompletableFuture<Integer> total = listQueryPageService.queryTotal(sql.toString(), null, tableNamesql.toString(), field, user);
        CompletableFuture<Integer> queryCount = listQueryPageService.queryListCount(field, sql.toString(), null, listQuery, user, tenantCode);
        CompletableFuture.allOf(list, queryCount).join();
        try {
            tableDataInfo.setRows(list.get());
            tableDataInfo.setTotal(queryCount.get());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return tableDataInfo;
    }

    /**
     * 查询只传门类信息的
     *
     * @param categoryId 门类id
     * @param listQuery  查询参数
     * @return java.lang.String
     * @author hbWang
     * @date 2023/6/29 15:29
     */
    public TableDataInfo queryCategory(String categoryId, ListQuery listQuery) {
        String tenantCode = SecurityUtils.getTenantCode();
        //查询门类信息
        Map<String, Object> categoryMap = listQueryMapper.selectTableData(tenantCode + Constants.BIG_TABLE_NAME, " ITEM_TABLE_NAME," +
                "FOLDER_TABLE_NAME,FILE_TABLE_NAME,TYPE ", " ID= " + categoryId).get(0);
        String tableNameFile = categoryMap.get("FILE_TABLE_NAME") == null ? "" : categoryMap.get("FILE_TABLE_NAME").toString();
        String tableNameFolder = categoryMap.get("FOLDER_TABLE_NAME") == null ? "" : categoryMap.get("FOLDER_TABLE_NAME").toString();
        String tableNameItem = categoryMap.get("ITEM_TABLE_NAME") == null ? "" : categoryMap.get("ITEM_TABLE_NAME").toString();
        String field = listQuery.getFiles();
        if (StringUtils.isNotBlank(field)) {
            field += ",CREATE_ID,IS_ENTITY,GDCS_ID,EFILE_COUNT,MJ";
        }
        //查询元数据方案信息
        List<Map<String, Object>> dataList = listQueryMapper.selectMDataListTableData(tenantCode + Constants.BIG_TABLE_M_DATA_LIST,
                " and t.GROUP_ID =" + listQuery.getGroupId() + " and t.FIELD_NAME in ( '" + field.replace(",", "','") + "' )");
        //处理查询字段
        Map<String, String> map = initializationFiled(dataList);
        String unionSql = " UNION ALL ";
        StringBuilder sql = new StringBuilder("");
        //件
        if (StringUtils.isNotBlank(tableNameFile)) {
            sql.append("select DA_ID, SUB_TABLE_NAME," + map.get("file") + " from " +
                    tenantCode + Constants.BIG_TABLE_YQDA + " where IS_DEL = 0 and STATE = '5' ");
            sql.append(" and SUB_TABLE_NAME = '" + tableNameFile + "' ");
        }
        //卷
        if (StringUtils.isNotBlank(tableNameFolder)) {

            sql.append(unionSql);
            sql.append("select " + " FOLDER_ID as DA_ID , SUB_TABLE_NAME," + map.get("folder") + " from " +
                    tenantCode + Constants.BIG_TABLE_YQFOLDER + " where IS_DEL = 0 and STATE = '5' ");
            sql.append(" and SUB_TABLE_NAME = '" + tableNameFolder + "' ");
        }
        //项目
        if (StringUtils.isNotBlank(tableNameItem)) {
            sql.append(unionSql);
            sql.append("select " + " ITEM_ID as DA_ID,  SUB_TABLE_NAME , " + map.get("item") + " from " +
                    tenantCode + Constants.BIG_TABLE_YQITEM + " where IS_DEL = 0 and STATE = '5' ");
            sql.append(" and SUB_TABLE_NAME = '" + tableNameItem + "' ");
        }
        //拼接查询条件
        String query = concatQueryCondition(listQuery, listQuery.getFiles(), " t.");
        String fieldl = map.get("filde") + " ,t.DA_ID,t.SUB_TABLE_NAME ";
        if (StringUtils.isBlank(listQuery.getOrder())) {
            String appData = listQueryMapper.selectAppData(tenantCode + "_TABLEHEAD ", "CONTENT", "  " +
                    "type= '-1' and menu_id= '" + listQuery.getMenuId() + "' and CATEGORY_ID= '" + listQuery.getCategoryId() + "' and qzh ='" + listQuery.getQzh() + "' ");
            if (StringUtils.isNotBlank(appData)) {
                String[] split = appData.split(",");
                List<String> order = new ArrayList<>();
                for (String s : split) {
                    if (!s.contains(" NONE") && fieldl.contains(s.replace(" ASC", "").replaceAll(" DESC", ""))) {
                        order.add(s);
                    }
                }
                if (order != null && order.size() > 0) {
                    listQuery.setOrder(order.stream().collect(Collectors.joining(" NULLS LAST, ")) + " NULLS LAST ");
                }

            }
        }
        //异步
        SysUser user = SecurityUtils.getLoginUser().getSysUser();
        TableDataInfo tableDataInfo = new TableDataInfo();
        tableDataInfo.setCode(HttpStatus.SUCCESS);
        tableDataInfo.setMsg("查询成功");
        if (listQuery.getCount()) {
            Integer total = listQueryPageService.queryTotal(sql.toString(), query, fieldl, user);
            tableDataInfo.setTotal(total);
            return tableDataInfo;
        }
        CompletableFuture<List<Map<String, Object>>> list = listQueryPageService.queryList(fieldl, sql.toString(), query, listQuery, user, tenantCode);
        // CompletableFuture<Integer> total = listQueryPageService.queryTotal(sql.toString(), query, sql.toString(), fieldl, user);
        CompletableFuture<Integer> queryCount = listQueryPageService.queryListCount(fieldl, sql.toString(), query, listQuery, user, tenantCode);
        CompletableFuture.allOf(list, queryCount).join();
        try {
            tableDataInfo.setRows(list.get());
            tableDataInfo.setTotal(queryCount.get());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return tableDataInfo;
    }

    /**
     * 查询只传分类信息
     *
     * @param
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @author hbWang
     * @date 2023/6/29 16:00
     */
    public TableDataInfo queryType(String type, ListQuery listQuery) {
        String roleType = null;
        if (type.equals("1")) {
            roleType = "1,3";
        } else if (type.equals("0")) {
            roleType = "0,1,3";
        } else {
            roleType = type;
        }
        List<Map<String, Object>> mapList = queryCategoryIds(roleType, listQuery.getMenuId(), listQuery.getQzh());
        if (ObjectUtils.isEmpty(mapList)) {
            return null;
        }
        //获取当前登录用户信息
        String tenantCode = SecurityUtils.getTenantCode();
        StringBuffer sql = new StringBuffer("");
        String fields = listQuery.getFiles();
        if (StringUtils.isNotBlank(fields)) {
            fields += ",CREATE_ID,IS_ENTITY,GDCS_ID,EFILE_COUNT,MJ";
        }
        String subTableName = "";
        //查询元数据方案信息
        List<Map<String, Object>> dataList = listQueryMapper.selectMDataListTableData(tenantCode + Constants.BIG_TABLE_M_DATA_LIST,
                " and t.TYPE in(" + roleType + ") and t.FIELD_NAME in ( '" + fields.replace(",", "','") + "' )");
        String field = dataList.stream().map(m -> m.get("FIELD_NAME").toString()).distinct().collect(Collectors.joining(","));
        //组件信息
        if (type.equals("0")) {
            if (!field.contains("EFILE_COUNT")) {
                field += ",EFILE_COUNT";
            }
            sql.append(" select DA_ID,SUB_TABLE_NAME, " + field + " from " + tenantCode + Constants.BIG_TABLE_YQDA +
                    " where IS_DEL = 0 and STATE = '5' ");
            subTableName = mapList.stream().filter(f -> f.containsKey("FILE_TABLE_NAME") && f.get("FILE_TABLE_NAME") != null)
                    .map(m -> m.get("FILE_TABLE_NAME").toString()).collect(Collectors.joining("','"));
        }
        //组卷
        if (type.equals("1")) {
            sql.append(" select FOLDER_ID as DA_ID, SUB_TABLE_NAME, " + field + " from " + tenantCode + Constants.BIG_TABLE_YQFOLDER +
                    " where IS_DEL = 0 and STATE = '5' ");
            subTableName = mapList.stream().filter(f -> f.containsKey("FOLDER_TABLE_NAME") && f.get("FOLDER_TABLE_NAME") != null)
                    .map(m -> m.get("FOLDER_TABLE_NAME").toString()).collect(Collectors.joining("','"));
        }
        //项目
        if (type.equals("3")) {
            sql.append(" select ITEM_ID as DA_ID,SUB_TABLE_NAME, " + field + " from " + tenantCode + Constants.BIG_TABLE_YQITEM +
                    " where IS_DEL = 0 and STATE = '5' ");
            subTableName = mapList.stream().filter(f -> f.containsKey("ITEM_TABLE_NAME") && f.get("ITEM_TABLE_NAME") != null)
                    .map(m -> m.get("ITEM_TABLE_NAME").toString()).collect(Collectors.joining("','"));
        }
        //拼接查询条件
        sql.append(concatQueryCondition(listQuery, field, ""));
        sql.append(" and SUB_TABLE_NAME in ('" + subTableName + "') ");
        //返回数据
        field = field + " ,DA_ID,SUB_TABLE_NAME ";
        if (StringUtils.isBlank(listQuery.getOrder())) {
            String appData = listQueryMapper.selectAppData(tenantCode + "_TABLEHEAD ", "CONTENT", "  " +
                    "type= " + listQuery.getType() + " and menu_id= '" + listQuery.getMenuId() + "' and CATEGORY_ID= '-1' and qzh ='" + listQuery.getQzh() + "' ");
            if (StringUtils.isNotBlank(appData)) {
                String[] split = appData.split(",");
                List<String> order = new ArrayList<>();
                for (String s : split) {
                    if (!s.contains(" NONE") && field.contains(s.replace(" ASC", "").replaceAll(" DESC", ""))) {
                        order.add(s);
                    }
                }
                if (order != null && order.size() > 0) {
                    listQuery.setOrder(order.stream().collect(Collectors.joining(" NULLS LAST, ")) + " NULLS LAST ");
                }

            }
        }
        //异步
        SysUser user = SecurityUtils.getLoginUser().getSysUser();
        TableDataInfo tableDataInfo = new TableDataInfo();
        tableDataInfo.setCode(HttpStatus.SUCCESS);
        tableDataInfo.setMsg("查询成功");
        if (listQuery.getCount()) {
            Integer total = listQueryPageService.queryTotal(sql.toString(), null, field, user);
            tableDataInfo.setTotal(total);
            return tableDataInfo;
        }
        CompletableFuture<List<Map<String, Object>>> list = listQueryPageService.queryList(field, sql.toString(), null, listQuery, user, tenantCode);
        //   CompletableFuture<Integer> total = listQueryPageService.queryTotal(sql.toString(), null, sumsubTableNamesql.toString(), field, user);
        CompletableFuture<Integer> queryCount = listQueryPageService.queryListCount(field, sql.toString(), null, listQuery, user, tenantCode);
        CompletableFuture.allOf(list, queryCount).join();
        try {
            tableDataInfo.setRows(list.get());
            tableDataInfo.setTotal(queryCount.get());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return tableDataInfo;
    }


    //拼接前端查询条件
    @Override
    public String concatQueryCondition(ListQuery listQuery, String field, String t) {
        StringBuilder queryCondition = new StringBuilder();
        //拼接前端查询条件
        if (listQuery.getQueryParams() != null && listQuery.getQueryParams().size() > 0) {
            listQuery.getQueryParams().forEach(q -> {
                String[] queryValue = new String[2];    //查询值
                String queryType = q.getQueryType();      //查询类型
                String showType = q.getShowType();        //展示类型
                String fieldName = q.getColumn();
                if ("4".equals(queryType)) {    //区间查询会有2个值
                    queryValue[0] = q.getValue();        //根据查询项获取对应的查询值
                    queryValue[1] = q.getValueTwo();
                } else {
                    queryValue[0] = q.getValue().replaceAll("'", "''");        //根据查询项获取对应的查询值
                }
                //logger.debug("queryColumns["+j+"] = "+queryColumns[j]+"--"+queryValue[0]);
                queryCondition.append(getQueryCriteriaByType(fieldName, showType, queryType, queryValue, field));
            });
        }
        return queryCondition.toString();
    }

    /**
     * <p>Title: getQueryCriteriaByType</p>
     * <p>Description: 根据传入的类型type 组合查询条件</p>
     *
     * @param column   列名
     * @param showType 查询类型
     *                 0	不参加查询	暂不考虑;
     *                 1	精确查询		= '匹配值';
     *                 2	模糊查询		like '%匹配值%';
     *                 3	左匹配查询	like '匹配值%';
     *                 4	区间查询		'匹配值1'<列<'匹配值2'	?是否包含=;
     *                 5	列表查询		不做处理;
     *                 6	单选对话框	不做处理;
     *                 7	多选对话框	不做处理;
     *                 8	多词检索		分词 以空格为标志;
     * @param values   查询值
     * @return
     */
    public String getQueryCriteriaByType(String column, String showType, String queryType, String[] values, String field) {
        String criteria = " ";
        Integer type = Integer.parseInt(queryType);
        switch (type) {
            case 0: //不参加查询	暂不考虑;
                criteria = " ";
                break;
            case 1: //精确查询	= '匹配值';
                criteria += " and " + column + " = '" + values[0] + "' ";
                break;
            case 2: //模糊查询	like '%匹配值%';
                criteria += " and " + column + " like '%" + values[0] + "%' ";
                break;
            case 3: //左匹配查询	like '匹配值%';
                criteria += " and " + column + " like '" + values[0] + "%' ";
                break;
            case 4: //区间查询	'匹配值1'<=列<='匹配值2'
                if (StringUtils.isNotEmpty(values[0])) {
                    criteria += " and '" + values[0] + "' <= " + column + " ";
                }
                if (StringUtils.isNotEmpty(values[1])) {
                    criteria += " and " + column + " <= '" + values[1] + "' ";
                }
                break;
            case 5: //列表查询	不做处理;
                criteria = " ";
                break;
            case 6: //单选对话框	不做处理;
                criteria = " ";
                break;
            case 7: //多选对话框	不做处理;
                criteria = " and " + column + " in (" + values[0] + ") ";
                break;
            case 8: //多词检索	分词 以空格为标志;	多词检索中 如果有查询列里的值存在空格 怎么处理 (查询时使用""将带空格需要整体查询的值标记 , 例如:"A B")
                String tenantCode = SecurityUtils.getTenantCode();
                String tableName = tenantCode + "_YQTYC";
                List<String> list = listQueryMapper.selectDataList(tableName, "tyc", " primary_word = '" + values[0] + "' and STATUS = '1' ");
                if (ObjectUtils.isNotEmpty(list)) {
                    values[0] = values[0] + "|" + list.stream().collect(Collectors.joining("|")).replaceAll(",", "|");
                }
                if (dataBaseId.equalsIgnoreCase(DbIdEnum.OSCAR.getCode())) {
                    String[] split = field.split(",");
                    List<String> ff = new ArrayList<>();
                    for (String s : split) {
                        ff.add("NVL(" + s + ",'')");
                    }
                    criteria = " and regexp_like( CONCAT( " + ff.stream().collect(Collectors.joining(",'--' ,")) + " ) ,'(" + values[0] + ")')>0 ";
                } else if (dataBaseId.equalsIgnoreCase(DbIdEnum.HIGHGO.getCode())) {
                    String finalField = field.replaceAll(",", ",'--' ,");
                    criteria = " and regexp_match( CONCAT( " + finalField + " ) ,'(" + values[0] + ")') is not null ";
                } else {
                    String finalField = field.replaceAll(",", ",'--' ,");
                    criteria = " and regexp_like( CONCAT( " + finalField + " ) ,'(" + values[0] + ")')>0 ";
                }
                break;
            default:
                break;
        }
        return criteria;
    }

    /**
     * 处理初始化查询字段
     *
     * @param list
     * @return
     */
    @Override
    public Map<String, String> initializationFiled(List<Map<String, Object>> list) {

        Pattern pattern = Pattern.compile("\\(|\\)|\\（|\\）");  // 匹配左括号"("或右括号")"
        List<Map<String, String>> tabulationData = list.stream().collect(Collectors.groupingBy(c -> c.get("FIELD_NAME"))).values().stream().map(a ->
        {
            String capion = a.stream().map(dd -> String.valueOf(dd.get("FIELD_CAPTION")).replaceAll(" ", "")).distinct().collect(Collectors.joining(""));
            Matcher matcher = pattern.matcher(capion);
            Map<String, String> mm = new HashMap<>();
            mm.put("FIELD_NAME", String.valueOf(a.get(0).get("FIELD_NAME")));
            mm.put("FIELD_CAPTION", matcher.replaceAll(""));
            mm.put("SHOWTYPE", String.valueOf(a.get(0).get("SHOWTYPE")));
            mm.put("TYPE", String.valueOf(a.get(0).get("TYPE")));
            return mm;
        }).collect(Collectors.toList());
        Map<String, List<Map<String, Object>>> type = list.stream().collect(Collectors.groupingBy(c -> c.get("TYPE").toString()));

        List<String> file = new ArrayList<>();
        List<String> folder = new ArrayList<>();
        List<String> item = new ArrayList<>();
        Iterator<String> iterator = type.keySet().iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            List<String> fildList = type.get(key).stream().map(m -> m.get("FIELD_NAME").toString()).distinct().collect(Collectors.toList());
            if ("0".equals(key)) {
                file.addAll(fildList);
            }
            if ("1".equals(key)) {
                folder.addAll(fildList);
            }
            if ("3".equals(key)) {
                item.addAll(fildList);
            }
        }
        List<String> minuss = new ArrayList<>();
        minuss.addAll(file);
        minuss.addAll(folder);
        minuss.addAll(item);
        List<String> minus = minuss.stream().distinct().collect(Collectors.toList());
        String filde = "";
        String fildeQuery = "";
        for (String mi : minus) {
            List<Map<String, String>> fieldName = tabulationData.stream().filter(e -> e.get("FIELD_NAME").equals(mi)).collect(Collectors.toList());
            if ("".equals(filde)) {
                filde = "t." + fieldName.get(0).get("FIELD_CAPTION") + " as " + fieldName.get(0).get("FIELD_NAME");
                fildeQuery = fieldName.get(0).get("FIELD_NAME");
                continue;
            }
            filde = "t." + fieldName.get(0).get("FIELD_CAPTION") + " as " + fieldName.get(0).get("FIELD_NAME") + "," + filde;
            fildeQuery = fieldName.get(0).get("FIELD_NAME") + "," + fildeQuery;
        }
        Map<String, String> map = new HashMap<>();
        map.put("file", manageQueryFilde(minus, file, tabulationData));
        map.put("folder", manageQueryFilde(minus, folder, tabulationData));
        map.put("item", manageQueryFilde(minus, item, tabulationData));
        map.put("filde", filde);
        map.put("fildeQuery", fildeQuery);
        map.put("fileCount", file.stream().collect(Collectors.joining(",")));
        map.put("folderCount", folder.stream().collect(Collectors.joining(",")));
        map.put("itemCount", item.stream().collect(Collectors.joining(",")));
        return map;
    }

    /**
     * 处理查询字段的拼接
     *
     * @param minus      所有字段
     * @param stringList 分类字段
     * @param maps       所有元数据方案字段
     * @return
     */
    public String manageQueryFilde(List<String> minus, List<String> stringList, List<Map<String, String>> maps) {
        List<String> nullFilde = minus.stream().filter(mi -> !stringList.contains(mi)).collect(Collectors.toList());
        List<String> fileNames = new ArrayList<>();
        for (String f : nullFilde) {
            List<Map<String, String>> fieldName = maps.stream().filter(e -> e.get("FIELD_NAME").equals(f)).collect(Collectors.toList());
            fileNames.add(fieldName.get(0).get("FIELD_CAPTION"));
        }
        String ss = "";
        if (fileNames != null && fileNames.size() > 0) {
            ss = "null as " + fileNames.stream().collect(Collectors.joining(" ,null as "));
        }
        for (String le : stringList) {
            List<Map<String, String>> fieldName = maps.stream().filter(e -> e.get("FIELD_NAME").equals(le)).collect(Collectors.toList());
            if (DbIdEnum.OSCAR.getCode().equalsIgnoreCase(dataBaseId)) {
                ss = "to_char(" + le + ")" + " as " + fieldName.get(0).get("FIELD_CAPTION") + "," + ss;
            } else if (DbIdEnum.KINGBASE.getCode().equalsIgnoreCase(dataBaseId)) {
                ss = "to_char(" + le + ")" + " as " + fieldName.get(0).get("FIELD_CAPTION") + "," + ss;
            } else if (DbIdEnum.HIGHGO.getCode().equalsIgnoreCase(dataBaseId)) {
                ss = " cast(" + le + " as varchar  )" + " as " + fieldName.get(0).get("FIELD_CAPTION") + "," + ss;
            } else {
                ss = le + " as " + fieldName.get(0).get("FIELD_CAPTION") + "," + ss;
            }
        }
        String field = sortByStr(Arrays.asList(ss.split(",")), "as").stream().collect(Collectors.joining(","));
        return field;
    }


    /**
     * st第一次出现分割字符串，st前的字符串大小排序
     *
     * @param list 对比的字符串列表
     * @param st   字符第一次出现的时候
     * @return
     */
    public static List<String> sortByStr(List<String> list, String st) {
        if (st == null || st == "") {
            return null;
        }
        HashMap<String, String> integerStringHashMap = new HashMap<>();
        for (int i = 0; i < list.size(); i++) {
            String str = list.get(i);
            // 如果list空则返回
            if (list.isEmpty()) {
                return null;
            }
            String integer = str.substring(str.lastIndexOf(st) + 3).replaceAll(" ", "");
            if (integerStringHashMap.get(integer) != null) {
                integer = integer + i;
                if (dataBaseId.equalsIgnoreCase(DbIdEnum.OSCAR.getCode())) {
                    str = str.trim() + 1;
                }
                if (dataBaseId.equalsIgnoreCase(DbIdEnum.KINGBASE.getCode())) {
                    str = str.trim() + 1;
                } else if (dataBaseId.equalsIgnoreCase(DbIdEnum.HIGHGO.getCode())) {
                    str = str.trim() + 1;
                }
            }
            integerStringHashMap.put(integer, str);
        }
        Set<String> sets = integerStringHashMap.keySet();
        List<String> keys = new ArrayList<>(sets);
        Collections.sort(keys);
        ArrayList<String> inputList = new ArrayList<>();
        for (String key : keys) {
            inputList.add(integerStringHashMap.get(key));
        }
        return inputList;
    }

    /**
     * 处理应用定义查询字段等
     *
     * @param categoryId
     * @param groupId
     * @param menuId
     * @param type
     * @return
     */
    public List<Map<String, Object>> mDataList(String categoryId, String groupId, String menuId, String type) {
        //获取当前登录用户信息
        String tenantCode = SecurityUtils.getTenantCode();
        StringBuilder sql = new StringBuilder("");
        if (StringUtils.isNotBlank(groupId)) {
            sql.append(" and t.GROUP_ID = '" + groupId + "' ");
            sql.append(" and t.TYPE = '" + type + "' ");
            //查询应用定义信息
            TenantApply tenantApplyQuery = tenantApplyMapper.selectYqdaApplyModelById(Long.valueOf(menuId),
                    Long.valueOf(categoryId), tenantCode + Constants.TABLE_YQ_APP);
            if (ObjectUtils.isNotEmpty(tenantApplyQuery)) {
                String appData = null;
                if ("0".equals(type)) {
                    appData = tenantApplyQuery.getJianlistfield();
                    if (StringUtils.isNotBlank(tenantApplyQuery.getJianquery()) && StringUtils.isNotBlank(appData)) {
                        appData = appData + "," + tenantApplyQuery.getJianquery();
                    }
                }
                if ("1".equals(type)) {
                    appData = tenantApplyQuery.getJuanlistfield();
                    if (StringUtils.isNotBlank(tenantApplyQuery.getJuanquery()) && StringUtils.isNotBlank(appData)) {
                        appData = appData + "," + tenantApplyQuery.getJuanquery();
                    }
                }
                if ("3".equals(type)) {
                    appData = tenantApplyQuery.getXiangmulistfield();
                    if (StringUtils.isNotBlank(tenantApplyQuery.getXiangmuquery()) && StringUtils.isNotBlank(appData)) {
                        appData = appData + "," + tenantApplyQuery.getXiangmuquery();
                    }
                }
                if (StringUtils.isNotBlank(appData)) {
                    appData += ",CREATE_ID,IS_ENTITY,GDCS_ID,EFILE_COUNT,MJ";
                    sql.append(" and t.FIELD_NAME in  ('" + appData.replace(",", "','") + "') ");
                } else {
                    sql.append(" AND ((t.IS_HIDDEN = 0 and t.IS_SYSTEM = 1 ) or t.FIELD_NAME in ('IS_ENTITY','GDCS_ID','CREATE_ID','EFILE_COUNT','MJ'))");
                }
            } else {
                sql.append(" AND ((t.IS_HIDDEN = 0 and t.IS_SYSTEM = 1 ) or t.FIELD_NAME in ('IS_ENTITY','GDCS_ID','CREATE_ID','EFILE_COUNT','MJ'))");
            }
        } //查询元数据方案信息
        List<Map<String, Object>> dataList = listQueryMapper.selectMDataListTableData(tenantCode + Constants.BIG_TABLE_M_DATA_LIST, sql.toString());

        return dataList;
    }

    /**
     * 查询元数据信息
     *
     * @param file
     * @param type
     * @param groupId
     * @return
     */
    public List<Map<String, Object>> appData(String file, String type, String groupId) {
        //获取当前登录用户信息
        String tenantCode = SecurityUtils.getTenantCode();
        StringBuilder sql = new StringBuilder(" and t.IS_HIDDEN = 0 ");
        sql.append(" and t.GROUP_ID = '" + groupId + "' ");
        sql.append(" and t.TYPE = '" + type + "' ");
        if (StringUtils.isNotBlank(file)) {
            sql.append(" and t.FIELD_NAME in  ('" + file.replace(",", "','") + "') ");
        }
        //查询元数据方案信息
        List<Map<String, Object>> dataList = listQueryMapper.selectMDataListTableData(tenantCode + Constants.BIG_TABLE_M_DATA_LIST,
                sql.toString());

        return dataList;
    }

    /**
     * 查询门类信息
     *
     * @param type
     * @param menuId
     * @return
     */
    public List<Map<String, Object>> queryCategoryIds(String type, String menuId, String qzh) {
        List<SysRole> roles = SecurityUtils.getLoginUser().getSysUser().getRoles();
        if (roles == null && roles.size() <= 0) {
            return null;
        }
        String collect = roles.stream().map(m -> String.valueOf(m.getRoleId())).collect(Collectors.joining(","));
        String tenantCode = SecurityUtils.getTenantCode();
        StringBuilder sql = new StringBuilder("");
        sql.append(" select c.GROUP_ID,c.ID,c.NAME,c.TYPE,c.ITEM_TABLE_NAME,c.FOLDER_TABLE_NAME,c.FILE_TABLE_NAME from " + tenantCode + Constants.BIG_TABLE_NAME_TREESROLE);
        sql.append(" tr LEFT JOIN " + tenantCode + Constants.BIG_TABLE_NAME_TREES);
        sql.append(" t ON t.ID = tr.TREE_ID ");
        sql.append(" LEFT JOIN " + tenantCode + Constants.BIG_TABLE_NAME);
        sql.append(" c ON t.CATEGORY_ID = c.ID  where c.IS_DEL = 0 and c.GROUP_ID is not null and t.TYPE='a' ");
        if (!SecurityUtils.isDagly()) {
            sql.append(" and tr.ROLE_ID IN (" + collect + ")");
            sql.append(" and tr.MENU_ID = '" + menuId + "' ");
        }
        if (StringUtils.isNotBlank(qzh) && !"-1".equals(qzh)) {
            sql.append(" and c.fonds_code ='" + qzh + "' ");
        }
        if (StringUtils.isNotBlank(type) && !"-1".equals(type)) {
            sql.append(" and c.TYPE in (" + type + ") ");
        }
        List<Map<String, Object>> categoryList = new ArrayList<>();
        //查询门类信息
        if (dataBaseId.equalsIgnoreCase(DbIdEnum.KINGBASE.getCode())) {
            categoryList = listQueryMapper.selectLeftJoinTableData(" GROUP_ID, ID,NAME,TYPE,ITEM_TABLE_NAME,FOLDER_TABLE_NAME,FILE_TABLE_NAME ", "", "(" + sql.toString() + ")");
        } else {
            categoryList = listQueryMapper.selectLeftJoinTableData(" GROUP_ID, ID,NAME,TYPE,ITEM_TABLE_NAME,FOLDER_TABLE_NAME,FILE_TABLE_NAME ", "", dataBaseId.equalsIgnoreCase(DbIdEnum.OSCAR.getCode()) ? "(" + sql.toString() + ")" : (dataBaseId.equalsIgnoreCase(DbIdEnum.HIGHGO.getCode()) ? "(" + sql.toString() + ")" : sql.toString()));
        }
        List<Map<String, Object>> categoryListd = new ArrayList<>();
        if (categoryList != null) {
            categoryListd = categoryList
                    .stream().collect(
                            Collectors.collectingAndThen(
                                    Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(m -> String.valueOf(m.get("ID"))))), ArrayList::new)
                    );
        }
        return categoryListd;
    }


    @Override
    public void downloadElectronics(JSONObject json, HttpServletResponse response) throws IOException {
        String path = sysConfigService.selectConfigByKey("PACK_PATH");
        if (StringUtils.isEmpty(path)) {
            throw new ServiceException("请查看PACK_PATH参数是否存在!");
        }
        JSONArray jsonArray = json.getJSONArray("dalist");
        String tenantCode = SecurityUtils.getTenantCode();
        List<Map<String, String>> daList = IntStream.range(0, jsonArray.size())
                .mapToObj(i -> {
                    JSONObject jsonObj = jsonArray.getJSONObject(i);
                    Map<String, Object> map = new HashMap<>();
                    for (String key : jsonObj.keySet()) {
                        map.put(key, jsonObj.get(key));
                    }
                    return map;
                }).collect(Collectors.toList()).stream().collect(Collectors.groupingBy(c -> c.get("subtablename"))).values().stream().map(m -> {
                    String subtablename = String.valueOf(m.get(0).get("subtablename"));
                    String id = m.stream().map(c -> String.valueOf(c.get("id"))).collect(Collectors.joining("','"));
                    String daids = null;
                    String efileName = null;
                    String type = subtablename.substring(subtablename.length() - 3, subtablename.length() - 2).toUpperCase();
                    List<Map<String, Object>> mapList = listQueryMapper.selectTableData(tenantCode + Constants.BIG_TABLE_NAME, " TYPE,EFILE_TABLE_NAME ",
                            " (FILE_TABLE_NAME= '" + subtablename + "' OR FOLDER_TABLE_NAME ='" + subtablename + "' OR ITEM_TABLE_NAME ='" + subtablename + "')  AND IS_DEL = 0 ");
                    if (mapList != null && mapList.size() > 0) {
                        efileName = String.valueOf(mapList.get(0).get("EFILE_TABLE_NAME"));
                        if ("X".equals(type)) {
                            List<Map<String, Object>> ids = listQueryMapper.selectLeftJoinTableData(" DA_ID", " SELECT fd.DA_ID FROM " + tenantCode + Constants.BIG_TABLE_NAME_ITEM + " it left join "
                                    + tenantCode + Constants.BIG_TABLE_FOLDER_NAME + " fd on it.FOLDER_ID = fd.FOLDER_ID WHERE it.ITEM_ID IN  ('" + id + "') ", null);
                            daids = ids.stream().map(a -> String.valueOf(a.get("DA_ID"))).collect(Collectors.joining("','"));
                        } else if ("V".equals(type)) {
                            List<Map<String, Object>> ids = listQueryMapper.selectTableData(tenantCode + Constants.BIG_TABLE_FOLDER_NAME, " DA_ID ", " FOLDER_ID IN  ('" + id + "') ");
                            daids = ids.stream().map(a -> String.valueOf(a.get("DA_ID"))).collect(Collectors.joining("','"));
                        } else {
                            daids = id;
                        }
                    }
                    Map<String, String> map = new HashMap<>();
                    map.put("fileName", efileName);
                    map.put("id", daids);
                    return map;
                }).collect(Collectors.toList());
        filePake(daList, path, response);

    }

    public void filePake(List<Map<String, String>> daList, String path, HttpServletResponse response) throws IOException {
        Long id = SnowflakeIdGenerator.generateId();
        Date startTime = new Date();
        BufferedInputStream br = null;
        OutputStream out = null;
        int i = 0;
        if (!path.endsWith("/")) {
            path += "/";
        }
        String fileName = id + "" + startTime.getTime() + ".zip";
        File packZip = new File(path + fileName);
        try {
            if (!packZip.exists()) {
                //判断该文件的上级目录是否存在
                if (!packZip.getParentFile().exists()) {
                    packZip.getParentFile().mkdirs();
                }
                String packPath = path + id + "" + startTime.getTime() + File.separator;
                File file = new File(packPath);
                if (file.exists()) {
                    //删除目录重新生成
                    FileUtils.deleteQuietly(file);
                } else {
                    file.mkdirs();
                }
                //通过门类ID获取档案列表
                for (Map<String, String> map : daList) {
                    String tableName = map.get("fileName");
                    String daIds = map.get("id");
                    List<Map<String, Object>> docList = listQueryMapper.selectTableData(tableName, " DOC_MNT,PATH,REAL_DOC_NAME,DOC_NAME  ", " con_table_id IN  ('" + daIds + "') and is_del=0 ");
                    //附件处理
                    for (Map<String, Object> docMap : docList) {
                        File efile = new File(String.valueOf(docMap.get("DOC_MNT")) + docMap.get("PATH"));
                        if (efile.exists()) {
                            File fileCopy = new File(file.getPath(), i + "-" + docMap.get("DOC_NAME"));
                            if (!fileCopy.exists()) fileCopy.createNewFile();
                            FileUtils.copyFile(efile, fileCopy);
                            log.info("电子文件目录[{},{}]", packPath, i + "-" + docMap.get("REAL_DOC_NAME"));
                        }
                        i++;
                    }
                }
                //打压缩包
                ZipUtils.zip(packPath, path + id + "" + startTime.getTime());
                log.info("借阅下载压缩包[{}]", path + id + "" + startTime.getTime());
                //生成后删除临时文件
                FileUtils.deleteQuietly(file);
                br = new BufferedInputStream(new FileInputStream(path + fileName));
                byte[] buf = new byte[1024];
                int len = 0;
                boolean isOnLine = true;
                response.reset(); // 非常重要
                response.setContentType("application/x-msdownload");
                response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
                out = response.getOutputStream();
                while ((len = br.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
                br.close();
                out.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("打包失败！");
        } finally {
            br.close();
            out.close();
        }
        if (packZip.exists()) packZip.delete();
    }
}
